package com.object.module.cbb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.object.configuration.utils.PageUtils;
import com.object.configuration.utils.Q;
import com.object.configuration.utils.Query;
import com.object.dao.cbb.CbbShoppingCartDao;
import com.object.module.cbb.entity.CbbShoppingCartEntity;
import com.object.module.cbb.entity.CddShopEntity;
import com.object.module.cbb.service.CbbShoppingCartService;
import com.object.module.cbb.service.CbbUserService;
import com.object.module.cbb.service.CddShopService;
import org.apache.commons.lang.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Service("cbbShoppingCartService")
public class CbbShoppingCartServiceImpl extends ServiceImpl<CbbShoppingCartDao, CbbShoppingCartEntity> implements CbbShoppingCartService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Value("${spike.shop.start.name}")
    private String SpikeStartName;
    @Autowired
    private Redisson redisson;
    @Autowired
    private CddShopService cddShopService;
    private Integer seckillSales = 0;

    @Autowired
    private CbbUserService userService;
    @Autowired
    private CddShopService shopService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<CbbShoppingCartEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)) {
            wrapper.eq("sc_sp_name", key);
        }
        IPage<CbbShoppingCartEntity> page = this.page(
                new Query<CbbShoppingCartEntity>().getPage(params),
                wrapper
        );
        for (CbbShoppingCartEntity record : page.getRecords()) {
            record.setUser(userService.getById(record.getScUrId()));
            record.setShop(shopService.getById(record.getScSpId()));
        }

        return new PageUtils(page);
    }

    /**
     * 商品秒杀
     *
     * @param spId
     * @param urId
     * @return
     */
    @Override
    @Transactional
    public Q spike(Long spId, Integer urId) {
        String Key = SpikeStartName + spId;
        String shopKey = SpikeStartName;
        //获取锁
        RLock lock = redisson.getLock(shopKey);
        //设置锁的过期时间  如果设置失败就会停留在这
        lock.lock(3, TimeUnit.MINUTES);

        //第一步查询秒杀商品是不是还在秒杀中
        try {
            Integer integer = (Integer) redisTemplate.opsForValue().get(Key);
            if (integer == null) {
                //当前商品的秒杀时间已经超过了
                return Q.error().message("此商品已经超时秒杀");
            }
            if (integer == 0) {
                //给秒杀商品添加销量
                cddShopService.updateSales(spId, seckillSales);
                //当前商品秒杀完了
                return Q.error().message("此商品秒杀完毕");
            }

            //秒杀 成功把我们秒杀的商品加入到我们的购物车里面去
            userAddsToCart(urId, spId, null);
            integer = integer - 1;
            seckillSales++;
            redisTemplate.opsForValue().set(Key, integer);
            // System.out.println("秒杀成功当前库存:" + integer);
        } finally {
            lock.unlock();
        }
        return Q.ok().message("商品秒杀成功");
    }


    /**
     * 用户把商品加入购物车
     *
     * @param urId
     * @param spId
     */
    public boolean userAddsToCart(Integer urId, Long spId, CbbShoppingCartEntity shoppingCartEntity) {
        CddShopEntity shop = cddShopService.getById(spId);
        if (null != shoppingCartEntity) {
            //说明我们当前加入购物车 的不是我们的秒杀商品
            // 直接加入
            double countPrice = shoppingCartEntity.getScCount() * shop.getSpSellingPrice();
            shoppingCartEntity.setScPriceCount(countPrice);
        } else {
            //秒杀加购
            shoppingCartEntity = new CbbShoppingCartEntity();
            shoppingCartEntity.setScCount(1);
            shoppingCartEntity.setScSpId(spId);
            shoppingCartEntity.setScPriceCount(shop.getSpSellingPrice());
            shoppingCartEntity.setScSpName(shop.getSpName());
            shoppingCartEntity.setScUrId(urId);
        }
        //最后保存到我们的购物车里面去
        return save(shoppingCartEntity);
    }

    @Override
    public List<CbbShoppingCartEntity> all(Integer urId) {
        QueryWrapper<CbbShoppingCartEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("sc_ur_id", urId);
        List<CbbShoppingCartEntity> list = list(wrapper);
        for (CbbShoppingCartEntity shopCart : list) {
            shopCart.setShop(cddShopService.getById(shopCart.getScSpId()));
        }
        return list;
    }

}